<?php
// +----------------------------------------------------------------------
// | 租户授权管理 类型服务
// +----------------------------------------------------------------------
// | 主要服务于租户授权管理数据处理
// +----------------------------------------------------------------------
// | 错误编码头 301xxx
// +----------------------------------------------------------------------

namespace common\service;

use common\model\TenantGrantModel;
use common\model\TenantUserModel;
use common\model\UserModel;
use support\ErrorCode;
use Throwable;

class TenantGrantService
{
    /**
     * @var FDDService
     */
    private $fddService;
    /**
     * @var TenantService
     */
    private $tenantService;

    public function __construct()
    {
        $this->fddService = new FDDService();
        $this->tenantService = new TenantService();
    }


    /**
     * 授权自动签署
     * @param $param
     * @param $fromTenantId
     * @return array|string
     * @throws \Exception
     */
    public function authorizedAutomaticSignature($param, $fromTenantId)
    {
        return teamones_request('teamones-saas', 'contract/create', [
            'data' => [
                'to_tenant_id' => $param['tenant_id'],
                'type' => 'contract_type_before_authsign',
                'from_tenant_id' => $fromTenantId,
            ]
        ]);
    }

    /**
     * 授权自动签署状态查询
     * @param $param
     * @return mixed
     */
    public function automaticSignatureStatus($param)
    {
        $fddCustomerId = $this->tenantService->getFddCustomerId([
            'id' => $param['tenant_id']
        ]);

        return $this->fddService->getAuthStatus($fddCustomerId);
    }

    /**
     * 获得授权记录
     * @param $filter
     * @return array
     */
    public function getTenantGrant($filter): array
    {
        $tenantGrant = model(TenantGrantModel::class)->where($filter)->find();
        if (empty($tenantGrant)) {
            throw_strack_exception("cant`t found tenantGrant record", ErrorCode::TENANT_GRANT_RECORD_NOT_FOUND);
        }
        return $tenantGrant;
    }

    /**
     * 修改授权状态
     * @param $id
     * @param $status
     * @return array|bool
     * @throws \Exception
     */
    public function modifyTenantGrantStatus($id, $status)
    {
        return model(TenantGrantModel::class)->modifyItem([
            'id' => $id,
            'status' => $status,
        ]);
    }

    /**
     * 查询
     * @param $params
     * @param $currentTenantId
     * @return array
     * @throws \Exception
     */
    public function select($params, $currentTenantId): array
    {
        $page = $params['param']['page'] ?? [1, C("database.database_max_select_rows")];
        $filter = $params['param']['filter'] ?? [];
        $fields = $params['param']['fields'] ?? null;
        $order = $params['param']['order'] ?? "tenant_grant.id DESC";

        $filter["tenant_grant.tenant_id"] = $currentTenantId;
        $filter["tenant_user.status"] = ['NEQ', TenantUserModel::STATUS_UNEMPLOYED];
        if (empty($fields)) {
            $fields = [
                "tenant_grant.id",
                "tenant_grant.user_id",
                "tenant_grant.tenant_id",
                "tenant_grant.status",
                "tenant_grant.created_by",
                "tenant_grant.created",
                "tenant_grant.updated",
                "tenant_grant.scope",
                "tenant.id",
                "tenant.name",
                "tenant.status",
                "tenant_user.id",
                "tenant_user.user_id",
                "user_authentication.id",
                "user_authentication.user_id",
                "user_authentication.real_name",
                "user_authentication.id_number",
                "user_authentication.phone",
                "user_authentication.bank_account",
                "user_authentication.reasons_for_failure",
                "user_authentication.status",
                "user_authentication.updated",
                "user_authentication.created_by",
                "user_authentication.created",
                "user_authentication.fdd_auth_status",
                "user_authentication.fdd_transaction_no",
                "user_authentication.fdd_auth_url",
                "user_authentication.fdd_auth_status_desc",
                "user_authentication.fdd_cert_status",
                "user_authentication.json",
            ];
            $fields = build_complex_query_fields($fields, '__');
            $fields = implode(',', $fields);
        }

        $total = model(TenantGrantModel::class)
            ->alias("tenant_grant")
            ->join("tenant tenant ON tenant.id = tenant_grant.tenant_id", "LEFT")
            ->join("tenant_user ON tenant_user.tenant_id = tenant.id AND tenant_user.user_id = tenant_grant.user_id")
            ->where($filter)
            ->count();
        $userIdList = model(TenantGrantModel::class)
            ->join("tenant tenant ON tenant.id = tenant_grant.tenant_id", "LEFT")
            ->join("tenant_user ON tenant_user.tenant_id = tenant.id AND tenant_user.user_id = tenant_grant.user_id")
            ->join('tenant_user_department on tenant_user_department.tenant_user_id = tenant_user.id', 'LEFT')
            ->join('tenant_user_role on tenant_user_role.tenant_user_id = tenant_user.id', 'LEFT')
            ->join("department ON tenant_user_department.department_id = department.id", "LEFT")
            ->join('role ON role.id = tenant_user_role.role_id', "LEFT")
            ->join("user_authentication ON user_authentication.user_id = tenant_user.user_id", "LEFT")
            ->where($filter)
            ->field('tenant_grant.user_id')
            ->page($page[0], $page[1])
            ->group("tenant_grant.user_id")
            ->order($order)
            ->select();

        $newRows = [];
        if (empty($userIdList)) {
            return [
                'total' => $total,
                'rows' => $newRows,
            ];
        }

        $rows = model(TenantGrantModel::class)
            ->join("tenant ON tenant.id = tenant_grant.tenant_id")
            ->join("tenant_user ON tenant_user.tenant_id = tenant.id AND tenant_user.user_id = tenant_grant.user_id")
            ->join("user_authentication ON user_authentication.user_id = tenant_user.user_id", "LEFT")
            ->where([
                'tenant_grant.user_id' => ['IN', array_column($userIdList, 'user_id')],
                'tenant_grant.tenant_id' => $currentTenantId,
            ])
            ->field($fields)
            ->order($order)
            ->select();

        $tenantUserIdList = array_column($rows, 'tenant_user__id');
        $tenantUserDepartmentRoleInfoList = TenantUserService::getInstance()->getTenantUserListDepartmentRole($tenantUserIdList);
        $userIdList = array_column($rows, 'tenant_grant__user_id', 'tenant_grant__user_id');
        $userIdList = array_merge($userIdList, array_column($rows, 'tenant_grant__created_by', 'tenant_grant__created_by'));

        $userMap = model(UserModel::class)->where(['id' => ['IN', implode(',', $userIdList)]])->field("id,name,phone,email,sex,active,is_system,is_identified")->select();
        $userMap = array_column($userMap, null, 'id');
        $rows = array_group_by($rows, 'tenant_grant__user_id');

        foreach ($rows as $userId => &$rowList) {
            $createdBy = $rowList[0]['tenant_grant__created_by'] ?? 0;
            foreach ($rowList as &$row) {
                $row = separate_complex_query_data($row);
                $row['department_info'] = $row['role_info'] = [];
                if (isset($tenantUserDepartmentRoleInfoList[$row['tenant_user']['id']])) {
                    $row = array_merge($row, $tenantUserDepartmentRoleInfoList[$row['tenant_user']['id']]);
                }
            }
            $baseInfo = $rowList[0];
            $baseInfo['user'] = $userMap[$userId] ?? null;
            $baseInfo['create_by'] = $userMap[$createdBy] ?? null;
            $newRows[] = $baseInfo;
        }
        return [
            'total' => $total,
            'rows' => $newRows,
        ];
    }

    /**
     * 删除授权
     * @param array $param
     * @return string[]
     */
    public function delete(array $param)
    {
        $res = ['ids'];
        $tenantGrants = model(TenantGrantModel::class)->where($param['param']['filter'])->select();
        foreach ($tenantGrants as $grant) {
            if ($grant['status'] === 'active') {
                try {
                    $this->fddService->authorization(['param' => ['id' => $grant['id'], 'operation' => 0]]);
                } catch (Throwable $e) {
                    trace(format_exception_info($e), 'ERR');
                }
            }
            model(TenantGrantModel::class)->where(['id' => $grant['id']])->delete();
            $res['ids'][] = $grant['id'];
        }
        return $res;
    }
}
